﻿import com.gamepackage.tilemap.*;
import com.gamepackage.tilemap.pathfinder.*;
import com.gamepackage.events.*;

class com.gamepackage.tilemap.pathfinder.Headquarter implements Pathfinder
{
	function addDeflection(  msg: String, exe: Executable ): Void {};
	function removeDeflection( msg: String, exe: Executable ): Boolean { return null };
	
	//-- ALL PUBLIC TO HAVE FASTER ACCESS
	var map: Array;
	
	var x1: Number
	var y1: Number

	var pathFound: Boolean;
	var foundPath: Array;
	var occ: Array;
	var agents: Array;

	//-- COUNTER FOR PATHFINDING OVER TIME
	private var maxCompEachFrame: Number;
	private var al: Number;
	private var frames: Number;
	private var computation: Thread;

	//-- EVENTS
	private var deflectEvent: Function;

	function Headquarter ( map: Array )
	{
		this.map = map;
		
		EventDeflector.initialize( this );
	}
	
	function setMaxCompEachFrame( maxCompEachFrame: Number ): Void
	{
		this.maxCompEachFrame = maxCompEachFrame;
	}
	
	function findPath( x0: Number , y0: Number , x1: Number , y1: Number ): Array
	{
		foundPath = new Array();
		agents = new Array();
		occ = new Array();
		pathFound = false;

		this.x1 = x1;
		this.y1 = y1;

		if ( ~map[ y0 ][ x0 + 1 ] & 1 ) new Agent( x0 + 1, y0, 1, [ { x: x0 + 1 , y: y0 } ], this );
		if ( ~map[ y0 ][ x0 - 1 ] & 1 ) new Agent( x0 - 1, y0, 2, [ { x: x0 - 1 , y: y0 } ], this );
		if ( ~map[ y0 + 1 ][ x0 ] & 1 ) new Agent( x0, y0 + 1, 4, [ { x: x0 , y: y0 + 1 } ], this );
		if ( ~map[ y0 - 1 ][ x0 ] & 1 ) new Agent( x0, y0 - 1, 8, [ { x: x0 , y: y0 - 1 } ], this );

		if ( maxCompEachFrame )
		{
			computation = new Thread( this, moveAgents, maxCompEachFrame );
			computation.start();
			
			frames = 0;
			al = agents.length;
		}
		else
		{
			var agent: Agent;
			var a: Number = agents.length;
			while ( 1 )
			{
				while ( --a > -1 )
				{
					agent = agents[a];
					if ( agent.move() )
					{
						if ( pathFound )
						{
							//-- clear memory
							deflectEvent( "onPathFound" , foundPath , 0 );
							delete agents;
							delete occ;
							return foundPath;
						};
					} else {
						agents.splice( a , 1 );
					}
				}
				a = agents.length;
			}
		}
	}
	
	function moveAgents ( maxCompEachFrame: Number )
	{
		var agent: Agent;
		var count: Number = 0;
		do
		{
			agent = agents[ --al ];
			if ( agent.move() )
			{
				if ( pathFound )
				{
					delete agents;
					delete occ;
					deflectEvent( "onPathFound" , foundPath , frames );
					computation.stop();
					break;
				};
			} else {
				agents.splice( al , 1 );
			}
			if ( al == 0 ) al = agents.length;
		} while ( ++count < maxCompEachFrame );
		frames++;
	}
}